;***********************************************************************
; printf.asm
;
; provides asm code for pre-scheduler print stuff
;
; Author: Aidan Goddard 11/7/14
;
; Uses portions of code from http://wiki.osdev.org/Spinlock
;
;***********************************************************************

section .data

; lock variable
unlock_control	dq 0


section .text

global lock_print
global unlock_print
global cpu_number_print

;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
; spinlock entry

lock_print:
	; attempt to acquire the lock
	mov			rdi, unlock_control
	mov			eax, 0
	lock bts	[rdi], eax
	jnc			.acquired
	
.retest:
	; check if the lock is free before trying again
	pause
	test		DWORD [rdi], 1
	jnz			.retest
	
	; lock is open, attempt to acquire it
	mov			eax, 0
	lock bts	[rdi], eax
	jc			.retest
	
.acquired:
	; lock is acquired, continue into critical region
	ret


;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
; spinlock exit

unlock_print:
	; release lock
	mov			rdi, unlock_control
	mov			[rdi], DWORD 0
	ret


;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
; get cpu number

cpu_number_print:
	str		rax
	sub		rax, 0x40
	shr		rax, 4
	ret